﻿using System;
using System.Collections.Generic;
using System.IO;
using SDT.CrawlSystem.Servers.Filters;
using SDT.ServiceSystem;
using SDT.Libraries.Utilities;
using SDT.CrawlSystem.Servers;
using SDT.CacheSystem;

namespace URLChannelTester
{
    /// <summary>
    /// Written by TungNX
    /// </summary>
    public sealed class UrlWorkUnit : WorkUnit
    {
        private static LogHelper Logger = new LogHelper("C:\\Log\\URLTEST.url.log");
        private static readonly IRAMCache<string, string> TheCache = new RAMCache<string, string>(10000);

        #region Filters
        private IUrlFilter uFilter = null;
        public IUrlFilter UFilter
        {
            get { return uFilter; }
        }

        private IWIDFilter iFilter = null;
        public IWIDFilter IFilter
        {
            get { return iFilter; }
        }
        //Chọn vùng web để lấy HTML. Để không bị lẫn html với vùng khác
        //Author: TungNX
        //Created Date : 23/12/2010
        private Filter rFilter = null;
        public Filter RFilter
        {
            get { return rFilter; }        
        }

        #endregion

        #region Results
        private string rawHtml = "";
        public string RawHtml
        {
            get { lock(this) return Ready ? rawHtml : null; }
            internal set { lock(this) rawHtml = value; }
        }

        private IList<string> wids = null;
        public IList<string> WIDs
        {
            get
            {
                if (wids != null)
                    return wids;

                if (Ready && Links != null && Links.Count > 0)
                {
                    wids = new List<string>(Links.Count);
                    foreach (var i in Links)
                        wids.Add(iFilter.GetWID(i.Href));
                }
                return wids;
            }
        }
      /// <summary>
      /// TungNX
      /// Modified Date: 24/2/2011
      /// Vùng dữ liệu rawHTML được tách ra thành vùng nhỏ hơn
      /// </summary>
        private IList<ImgDes> links = null;
        public IList<ImgDes> Links
        {
            get
            {
                if (links != null)
                    return links;

                #region Sửa vùng RawHTML Modified Date: 24/2/2011
                ////truong hop không định nghĩa phần từ HTML Filter, hệ thống không bị lỗi
                string txt = null;
                if (rFilter != null)
                {
                    if (this.RFilter.DataSource == Filter.Regions.CONTENT) // truong hop region là content thì mới bóc tách ra vùng cần lấy
                        RawHtml = this.RFilter.DoFilter(RawHtml, txt, ref txt, true);
                }

                if (Ready)
                  links = UrlParser.ParserUrls(RawHtml, UFilter,"");      
                //string txt = null;
                ////truong hop không định nghĩa phần từ HTML Filter, hệ thống không bị lỗi
                //if (rFilter != null)
                //{
                //    if (this.RFilter.DataSource == Filter.Regions.CONTENT) // truong hop region là content thì mới bóc tách ra vùng cần lấy
                //        RawHtml = this.RFilter.DoFilter(RawHtml, txt, ref txt, true);
                //}
                #endregion

                //if (Ready)
                //    links = UrlParser.FindUrls(RawHtml, UFilter, "");

                return links;
            }
        }

        public override void ClearResult()
        {
            lock (this)
            {
                RawHtml = "";
                if (wids != null) wids.Clear();
                wids = null;

                if (links != null) links.Clear();
                links = null;
            }
        }

        private string StandardizeUrl(string url)
        {
            var u = url;

            #region Remove url's prefix
            if (u.StartsWith(UrlPrefix))
                u = u.Substring(UrlPrefix.Length);
            #endregion

            #region Add back slash
            if (!u.StartsWith("/"))
                u = string.Format("/{0}", u);
            #endregion

            return u;
        }

        public void SaveResult()
        {
            if (!Ready)
                return;

            lock (this)
            {
                nurls = 0;

                if (Links != null && WIDs != null && Links.Count > 0)
                for (int i = 0; i < Links.Count; i++)
                {
                    var v = WIDs[i];
                    if (v == string.Empty)
                        continue;

                    var k = StandardizeUrl(Links[i].Href);
                    var img = Links[i].UrlImage;


                    //if (TheCache.CacheHit(k) == null)
                    //{
                    //    TheCache.Add(k, v);
                        lock (Logger)
                        {
                            Logger.AddEntry(String.Format("HIT:   {0} {1}", v, k));
                        }
                        
                    //}
                        
                }
                                

                ClearResult();
            }
        }
        #endregion

        #region Data members
        private int channelId = 0;
        public int ChannelId
        {
            get { return channelId; }
        }

        private int pageId = 0;
        public int PageId
        {
            get { return pageId; }
        }

        private string url = "";
        public string Url
        {
            get { return url; }
        }

        private string urlPrefix = "";
        public string UrlPrefix
        {
            get { return urlPrefix; }
        }

        private int pageNo = 0;
        public int PageNo
        {
            get { return pageNo; }
        }

        private int totalUrls = 0;
        public int TotalUrls
        {
            get { return totalUrls; }
        }

        private int nurls = 0;
        public int nUrls
        {
            get { return nurls; }
        }
        #endregion

        #region Constructors
        public UrlWorkUnit(int channelId, int pageId, IUrlFilter uFilter, IWIDFilter iFilter, string urlPrefix, string url, int pageNo) : base()
        {
            this.channelId = channelId;
            this.pageId = pageId;
            this.url = url;
            this.uFilter = uFilter;
            this.iFilter = iFilter;
            this.urlPrefix = urlPrefix;
            this.pageNo = pageNo;
        }
        /// <summary>
        /// Author: TungNX
        /// Created Date: 24/2/2011
        /// Thêm tham số khởi tạo Filter để lọc ra vùng cần lấy url
        /// </summary>
        /// <param name="channelId"></param>
        /// <param name="pageId"></param>
        /// <param name="uFilter"></param>
        /// <param name="iFilter"></param>
        /// <param name="rFilter"></param>
        /// <param name="urlPrefix"></param>
        /// <param name="url"></param>
        /// <param name="pageNo"></param>
        public UrlWorkUnit(int channelId, int pageId, IUrlFilter uFilter, IWIDFilter iFilter,Filter rFilter, string urlPrefix, string url, int pageNo): base()
        {
            this.channelId = channelId;
            this.pageId = pageId;
            this.url = url;
            this.uFilter = uFilter;
            this.iFilter = iFilter;
            this.urlPrefix = urlPrefix;
            this.rFilter = rFilter;
            this.pageNo = pageNo;
        }
        #endregion  
    }
}